package com.zhifei.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhifei.common.utils.Constant;
import com.zhifei.common.utils.DateUtils;
import com.zhifei.common.utils.Result;
import com.zhifei.common.utils.StringUtils;
import com.zhifei.common.utils.excel.ExcelUtils;
import com.zhifei.system.domain.EmployeeEntity;
import com.zhifei.system.domain.EmployeeMonthEntity;
import com.zhifei.system.domain.EmployeeSalaryEntity;
import com.zhifei.system.domain.dto.EmployeeSalaryExcelDTO;
import com.zhifei.system.domain.vo.EmployeeSalaryVo;
import com.zhifei.system.mapper.EmployeeSalaryMapper;
import com.zhifei.system.service.EmployeeMonthService;
import com.zhifei.system.service.EmployeeSalaryService;
import com.zhifei.system.service.EmployeeService;
import com.zhifei.system.util.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Service
public class EmployeeSalaryServiceImpl extends ServiceImpl<EmployeeSalaryMapper, EmployeeSalaryEntity> implements EmployeeSalaryService {

    @Autowired
    private EmployeeSalaryMapper employeeSalaryMapper;
    @Autowired
    private EmployeeMonthService employeeMonthService;
    @Autowired
    private EmployeeService employeeService;

    @Override
    public PageUtils pageSalary(Map<String, Object> params) {
        Page page = new Page(Long.parseLong((String)params.get(Constant.PAGE)),Long.parseLong((String)params.get(Constant.LIMIT)));
        String jobNum = (String) params.get("jobNum");
        String month = (String) params.get("month");
        List<EmployeeSalaryVo> employeeList = employeeSalaryMapper.pageSalary(page,jobNum,month);
        page.setRecords(employeeList);
        return new PageUtils(page);
    }

    @Override
    public Result importSalary(MultipartFile multipartFile,String month) {
        List<EmployeeSalaryEntity> employeeSalaryEntityList = new ArrayList<>();
        List<EmployeeMonthEntity> employeeMonthEntityList = new ArrayList<>();
        List<EmployeeEntity> employeeEntities = new ArrayList<>();
        List<Object> employeeSalaryExcelList = ExcelUtils.importExcel(multipartFile, new EmployeeSalaryExcelDTO());
        if (Objects.isNull(employeeSalaryExcelList)) {
            return Result.error("文件格式不支持，请采用样式模板");
        }
        Date yearmoDate = DateUtils.parseDate(month);
        Integer employeeSalaryCount = this.lambdaQuery().eq(EmployeeSalaryEntity::getMonth, yearmoDate).count();
        if(employeeSalaryCount>0){
            return Result.error("该月份数据已导入，请勿重复导入");
        }
        List<EmployeeEntity> employeeEntityList = employeeService.listDistinctEmployee();
        for (int i = 0; i < employeeSalaryExcelList.size(); i++) {
            EmployeeSalaryExcelDTO employeeSalaryExcelDTO = (EmployeeSalaryExcelDTO) employeeSalaryExcelList.get(i);
            if (StringUtils.isEmpty(employeeSalaryExcelDTO.getJobNum())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "工号不能为空！");
            }
            String jobNum = employeeSalaryExcelDTO.getJobNum();//工号
            String attendanceRequired = StringUtils.isEmpty(employeeSalaryExcelDTO.getAttendanceRequired())?"0":employeeSalaryExcelDTO.getAttendanceRequired();//甲方应出勤
            String actualAttendance = StringUtils.isEmpty(employeeSalaryExcelDTO.getActualAttendance())?"0":employeeSalaryExcelDTO.getActualAttendance();//甲方实际出勤
            String totalPayrollPayable = StringUtils.isEmpty(employeeSalaryExcelDTO.getTotalPayrollPayable())?"0":employeeSalaryExcelDTO.getTotalPayrollPayable();//应发工资总额
            String afterTaxPay = StringUtils.isEmpty(employeeSalaryExcelDTO.getAfterTaxPay())?"0":employeeSalaryExcelDTO.getAfterTaxPay();//税后实发
            String companyLaborCost = StringUtils.isEmpty(employeeSalaryExcelDTO.getCompanyLaborCost())?"0":employeeSalaryExcelDTO.getCompanyLaborCost();//企业人工成本
            String personalSocialSecurity = StringUtils.isEmpty(employeeSalaryExcelDTO.getPersonalSocialSecurity())?"0":employeeSalaryExcelDTO.getPersonalSocialSecurity();//个人社保
            String personalMedicalInsurance = StringUtils.isEmpty(employeeSalaryExcelDTO.getPersonalMedicalInsurance())?"0":employeeSalaryExcelDTO.getPersonalMedicalInsurance();//个人医保
            String personalAccumulationFund = StringUtils.isEmpty(employeeSalaryExcelDTO.getPersonalAccumulationFund())?"0":employeeSalaryExcelDTO.getPersonalAccumulationFund();//个人公积金
            String withholdingIncomeTax = StringUtils.isEmpty(employeeSalaryExcelDTO.getWithholdingIncomeTax())?"0":employeeSalaryExcelDTO.getWithholdingIncomeTax();//本月代扣个税
            String adjustmentAmount = StringUtils.isEmpty(employeeSalaryExcelDTO.getAdjustmentAmount())?"0":employeeSalaryExcelDTO.getAdjustmentAmount();//调整金额
            String companySocialSecurity = StringUtils.isEmpty(employeeSalaryExcelDTO.getCompanySocialSecurity())?"0":employeeSalaryExcelDTO.getCompanySocialSecurity();//公司社保
            String companyMedicalInsurance = StringUtils.isEmpty(employeeSalaryExcelDTO.getCompanyMedicalInsurance())?"0":employeeSalaryExcelDTO.getCompanyMedicalInsurance();//公司医保
            String companyAccumulationFund = StringUtils.isEmpty(employeeSalaryExcelDTO.getCompanyAccumulationFund())?"0":employeeSalaryExcelDTO.getCompanyAccumulationFund();//公司公积金
            //记录外派人员薪资发放记录明细表
            EmployeeSalaryEntity employeeSalaryEntity = new EmployeeSalaryEntity();
            employeeSalaryEntity.setJobNum(jobNum);
            employeeSalaryEntity.setMonth(yearmoDate);
            employeeSalaryEntity.setAttendanceRequired(attendanceRequired);
            employeeSalaryEntity.setActualAttendance(actualAttendance);
            employeeSalaryEntity.setTotalPayrollPayable(new BigDecimal(totalPayrollPayable));
            employeeSalaryEntity.setAfterTaxPay(new BigDecimal(afterTaxPay));
            employeeSalaryEntity.setCompanyLaborCost(new BigDecimal(companyLaborCost));
            employeeSalaryEntity.setPersonalSocialSecurity(new BigDecimal(personalSocialSecurity));
            employeeSalaryEntity.setPersonalMedicalInsurance(new BigDecimal(personalMedicalInsurance));
            employeeSalaryEntity.setPersonalAccumulationFund(new BigDecimal(personalAccumulationFund));
            employeeSalaryEntity.setWithholdingIncomeTax(new BigDecimal(withholdingIncomeTax));
            employeeSalaryEntity.setAdjustmentAmount(new BigDecimal(adjustmentAmount));
            employeeSalaryEntity.setCompanySocialSecurity(new BigDecimal(companySocialSecurity));
            employeeSalaryEntity.setCompanyMedicalInsurance(new BigDecimal(companyMedicalInsurance));
            employeeSalaryEntity.setCompanyAccumulationFund(new BigDecimal(companyAccumulationFund));
            employeeSalaryEntityList.add(employeeSalaryEntity);
            //记录外派人员每月实际详情表
            for(EmployeeEntity employeeEntity : employeeEntityList){
                if(employeeEntity.getJobNum().equals(jobNum)){
                    EmployeeMonthEntity employeeMonthEntity = new EmployeeMonthEntity();
                    employeeMonthEntity.setJobNum(jobNum);
                    employeeMonthEntity.setFullName(employeeEntity.getFullName());
                    employeeMonthEntity.setUserPost(employeeEntity.getUserPost());
                    employeeMonthEntity.setUserRank(employeeEntity.getUserRank());
                    employeeMonthEntity.setCustomerName(employeeEntity.getCustomerName());
                    employeeMonthEntity.setProjectName(employeeEntity.getProjectName());
                    employeeMonthEntity.setMonth(yearmoDate);
                    employeeMonthEntity.setSettlementAmount(null);
                    employeeMonthEntity.setCollectionAmount(null);
                    employeeMonthEntity.setCollectionDate(null);
                    employeeMonthEntity.setQuoteMonthPay(employeeEntity.getQuoteMonthPay());
                    employeeMonthEntity.setCompanyLaborCost(new BigDecimal(companyLaborCost));
                    employeeMonthEntity.setTaxRate(employeeEntity.getTaxRate());
                    BigDecimal quoteMonthPay = employeeMonthEntity.getQuoteMonthPay();
                    BigDecimal taxRate = employeeMonthEntity.getTaxRate();
                    BigDecimal CompanyLaborCost = employeeMonthEntity.getCompanyLaborCost();
                    BigDecimal taxAmount = quoteMonthPay.multiply((taxRate.divide(new BigDecimal(100),2, RoundingMode.HALF_UP)));//税额（报价月薪*税率）
                    employeeMonthEntity.setTaxAmount(taxAmount);
                    BigDecimal grossProfit = quoteMonthPay.subtract(CompanyLaborCost).subtract(taxAmount);//毛利（报价-薪资-社保公积金-税额）
                    employeeMonthEntity.setGrossProfit(grossProfit);
                    BigDecimal grossProfitRate = grossProfit.divide(quoteMonthPay,2,RoundingMode.HALF_UP);//毛利率（毛利/报价，如有调整实时更新，低于18%显示红色预警）
                    employeeMonthEntity.setGrossProfitRate(grossProfitRate);
                    BigDecimal companyManagementCost = quoteMonthPay.multiply(new BigDecimal(0.1));//公司管理成本（报价*10%）
                    employeeMonthEntity.setCompanyManagementCost(companyManagementCost);
                    BigDecimal riskReserve = quoteMonthPay.multiply(new BigDecimal(0.05));//风险储备金（报价*5%）
                    employeeMonthEntity.setRiskReserve(riskReserve);
                    BigDecimal travelExpenses = BigDecimal.ZERO;//差旅费用（初始值为0，后续接口取金蝶中人员差旅成本）
                    employeeMonthEntity.setTravelExpenses(travelExpenses);
                    BigDecimal marketingSubsidies = quoteMonthPay.multiply(new BigDecimal(0.01));//市场营销补贴（报价*1%）
                    employeeMonthEntity.setMarketingSubsidies(marketingSubsidies);
                    BigDecimal financialExpenses = quoteMonthPay.multiply(new BigDecimal(0.012));//财务费用（报价*1.2%）
                    employeeMonthEntity.setFinancialExpenses(financialExpenses);
                    String paymentMethod = employeeEntity.getPaymentMethod();
                    String businessSource = employeeEntity.getBusinessSource();
                    String userRank = employeeEntity.getUserRank();
                    BigDecimal salesCommission = BigDecimal.ZERO;//销售提成（毛利率<=18%为0，毛利率在18到30%为毛利*2%，毛利率在30%以上为毛利*2.5%）
                    BigDecimal commissionRate = BigDecimal.ZERO;//提成比例
                    if(grossProfitRate.compareTo(new BigDecimal(0.1))<=0){
                        commissionRate = BigDecimal.ZERO;
                    }else if(grossProfitRate.compareTo(new BigDecimal(0.1))>0 && grossProfitRate.compareTo(new BigDecimal(0.2))<=0){
                        commissionRate = new BigDecimal(0.01);
                    }else if(grossProfitRate.compareTo(new BigDecimal(0.2))>0 && grossProfitRate.compareTo(new BigDecimal(0.3))<=0){
                        commissionRate = new BigDecimal(0.03);
                    }else if(grossProfitRate.compareTo(new BigDecimal(0.3))>0){
                        commissionRate = new BigDecimal(0.05);
                    }
                    //鼓励月结回款，月结项目再加0.5%，独立新拓项目增加1%。
                    if(grossProfitRate.compareTo(new BigDecimal(0.1))>0){
                        if(StringUtils.isNotEmpty(paymentMethod) && paymentMethod.equals("月结")){
                            commissionRate = commissionRate.add(new BigDecimal(0.005));
                        }
                        if(StringUtils.isNotEmpty(businessSource) && businessSource.equals("个人开拓")){
                            commissionRate = commissionRate.add(new BigDecimal(0.01));
                        }
                    }
                    salesCommission = grossProfit.multiply(commissionRate);
                    BigDecimal recruitCommission = BigDecimal.ZERO;//招聘提成（按照初级250元/人、中级350元/人、高级岗位450元/人；毛利在30%以上增加100元/人）
                    if(StringUtils.isNotEmpty(userRank)){
                        if(userRank.equals("初级")){
                            recruitCommission = new BigDecimal(250);
                        }else if(userRank.equals("初中级") || userRank.equals("中级")){
                            recruitCommission = new BigDecimal(350);
                        }else if(userRank.equals("中高级") || userRank.equals("高级")){
                            recruitCommission = new BigDecimal(450);
                        }
                    }
                    if(grossProfitRate.compareTo(new BigDecimal(0.3))>0){
                        recruitCommission = recruitCommission.add(new BigDecimal(100));
                    }
                    employeeMonthEntity.setSalesCommission(salesCommission);//销售提成（毛利率<=18%为0，毛利率在18到30%为毛利*2%，毛利率在30%以上为毛利*2.5%）
                    employeeMonthEntity.setRecruitCommission(recruitCommission);
                    employeeMonthEntity.setPaymentMethod(paymentMethod);
                    employeeMonthEntity.setBusinessSource(businessSource);
//                    BigDecimal talentServiceCommission = grossProfit.multiply(new BigDecimal(0.02));//人才服务部提成（毛利*2%）
                    BigDecimal talentServiceCommission = BigDecimal.ZERO;
                    employeeMonthEntity.setTalentServiceCommission(talentServiceCommission);
                    BigDecimal netProfit = grossProfit.subtract(companyManagementCost).subtract(riskReserve).subtract(travelExpenses)
                            .subtract(marketingSubsidies).subtract(financialExpenses).subtract(salesCommission).subtract(talentServiceCommission).subtract(recruitCommission);//纯利（毛利-公司管理成本-风险储备金-差旅费用-市场营销补贴-财务费用-销售提成-人才服务部提成）
                    employeeMonthEntity.setNetProfit(netProfit);
                    BigDecimal netProfitRate = netProfit.divide(quoteMonthPay,2,RoundingMode.HALF_UP);//纯利率（纯利/报价）
                    employeeMonthEntity.setNetProfitRate(netProfitRate);
                    employeeMonthEntity.setServiceManager(employeeEntity.getServiceManager());
                    employeeMonthEntity.setRecruitHr(employeeEntity.getRecruitHr());
                    employeeMonthEntityList.add(employeeMonthEntity);
                    //更新employee表薪资和社保公积金
//                        employeeEntity.setMonthPay(employeeSalaryEntity.getTotalPayrollPayable());
                    employeeEntity.setSocialSecurity(employeeSalaryEntity.getCompanySocialSecurity().add(employeeSalaryEntity.getCompanyMedicalInsurance())
                            .add(employeeSalaryEntity.getCompanyAccumulationFund()));
                        employeeEntities.add(employeeEntity);
                }
            }
        }
        this.saveBatch(employeeSalaryEntityList);
        employeeMonthService.saveBatch(employeeMonthEntityList);
        employeeService.caclPriceBatch(employeeEntities);
        return Result.success("导入成功");
    }
}
